﻿package net.roading.net
{
	/*soap caller */
	import flash.events.Event;
	import flash.events.EventDispatcher;
	//
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.net.URLRequestMethod;
	import flash.net.URLRequestHeader;
	//
	import net.roading.events.SoapEvent;
	//
	import net.roading.data.XMLToObject;
	//
	public class SoapCaller
	{
		private var soap:Namespace = new Namespace("http://schemas.xmlsoap.org/soap/envelope/");
		private var soapXML:XML = <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
									xmlns:xsd="http://www.w3.org/2001/XMLSchema"
									xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body/></soap:Envelope>;
		private var urlLoader:URLLoader;
		private var urlRequest:URLRequest;
		private var targetMethodName:String;
		//
		private var response:EventDispatcher;
		private var args:Array;
		private var argNames:Array;
		//
		public function SoapCaller(wsUrl, wsNsName, argNames, methodName, response, args)
		{
			urlLoader = new URLLoader();
			urlRequest = new URLRequest();
			urlLoader.addEventListener("complete", completeHandler);
			urlLoader.addEventListener("ioError", ioerrorHandler);
			//
			this.response = response;
			this.args = args;
			this.argNames = argNames;
			//
			targetMethodName = methodName;
			var methodXML:XML = XML("<" + methodName + " xmlns=\"" + wsNsName + "\"/>");
			//参数列表
			for (var i=0; i<argNames.length; i++)
			{
				//trace("<" + argNames[i].name +">" + args[i] + "</" + argNames[i].name + ">");
				methodXML.appendChild( new XML("<" + argNames[i].name +">" + args[i] + "</" + argNames[i].name + ">") );
				//trace(argNames[i].name,"===",args[i]);
			}
			var tempXML:XML = soapXML;
			tempXML.soap::["Body"].appendChild(methodXML);
			if(wsNsName.lastIndexOf("/") == wsNsName.length - 1) wsNsName = wsNsName.substr(0, wsNsName.length - 1);
			urlRequest.url = wsUrl + "?op=" + methodName;            
			urlRequest.method = URLRequestMethod.POST;
			urlRequest.requestHeaders.push(new URLRequestHeader("Content-Type", "text/xml;charset=utf-8"));        
			urlRequest.requestHeaders.push(new URLRequestHeader("SOAPAction", wsNsName + "/" + methodName));
			urlRequest.data = tempXML;
			urlLoader.load(urlRequest);
		}
		//
		private function parseResultXml(xml:XML):Object
		{
			return XMLToObject.to(xml,true).Envelope.Body[targetMethodName+"Response"][targetMethodName+"Result"];
		}
		//
		private function completeHandler(e:Event):void
		{
			var xml:XML = new XML(e.target.data);
			var o = parseResultXml(xml);
			response.dispatchEvent(new SoapEvent("complete", {name:targetMethodName, data:o, xml:xml}));
		}
		//
		private function ioerrorHandler(e:Event):void
		{
			//调用出错
			//出错的原因有可能是提交的参数类型不匹配,下面是参数列表
			trace("/*****************************************************************************/");
			trace("soap caller error");
			trace("args list:");
			for(var i=0;i<argNames.length;i++)
			{
				trace("argName: ",argNames[i].name,"\targType: ",argNames[i].type,"\targValue: ",args[i]);
			}
			trace("/*****************************************************************************/");
			response.dispatchEvent(new SoapEvent("ioError", {e:e}));
		}
	}
}